package net.chenlin.dp.modules.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;

/**
 * @author Yangsm
 * @ClassName: ExcelUtil
 * @Description: TODO
 * @date 2023年08月02日 17:10
 */
public class ExcelUtil {

    private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);

    private ExcelUtil(){}

    /**
     * 导出Excel(一个sheet)
     *
     * @param response  HttpServletResponse
     * @param list      数据list
     * @param fileName  导出的文件名
     * @param sheetName 导入文件的sheet名
     * @param clazz 实体类
     */
    public static <T> void  writeExcel(HttpServletResponse response, HttpServletRequest request,
                                       List<T> list, String fileName, String sheetName, Class<T> clazz) {
        OutputStream outputStream = handleRequestResponse(response, request, fileName);
        EasyExcel.write(outputStream, clazz).sheet(sheetName).doWrite(list);
    }

    /**
     * 导出Excel(两个sheet)
     * @param response  HttpServletResponse
     * @param fileName  导出的文件名
     * @param list      数据list
     * @param sheetName 导入文件的sheet名
     * @param clazz 实体类
     * @param listTwo
     * @param clazzTwo
     */
    public static <T,T1> void  writeTwoSheetExcel(HttpServletResponse response, HttpServletRequest request, String fileName,
                                                  List<T> list, String sheetName, Class<T> clazz,
                                                  List<T1> listTwo, String sheetNameTwo, Class<T1> clazzTwo) {
        OutputStream outputStream = handleRequestResponse(response, request, fileName);
        ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
        WriteSheet sheet1 = EasyExcel.writerSheet(0, sheetName).head(clazz).build();
        WriteSheet sheet2 = EasyExcel.writerSheet(1, sheetNameTwo).head(clazzTwo).build();
        excelWriter.write(list, sheet1).write(listTwo, sheet2);
        excelWriter.finish();
    }


    /**
     * 导出Excel(带样式)
     *
     * @return
     */
    public static  <T> void writeStyleExcel(HttpServletResponse response, HttpServletRequest request,
                                            List<T> list, String fileName, String sheetName, Class<T> clazz) {
        //表头策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        //背景浅灰
        headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short)20);
        headWriteCellStyle.setWriteFont(headWriteFont);

        //内容策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 否则无法显示背景颜色；头默认了FillPatternType
        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        //背景浅绿
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
        WriteFont contentWriteFont = new WriteFont();
        //字体大小
        contentWriteFont.setFontHeightInPoints((short)15);
        contentWriteCellStyle.setWriteFont(contentWriteFont);

        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

        OutputStream outputStream = handleRequestResponse(response, request, fileName);
        EasyExcel.write(outputStream, clazz).registerWriteHandler(horizontalCellStyleStrategy).sheet(sheetName).doWrite(list);

    }


    /**
     * 导出Excel(动态表头)
     * write时不传入class,table时传入并设置needHead为false
     * @return
     */
    public static  <T> void writeDynamicHeadExcel(HttpServletResponse response,List<T> list, String fileName, String sheetName, Class<T> clazz,List<List<String>> headList) {
        OutputStream outputStream = getOutputStream(response, fileName);
        EasyExcel.write(outputStream)
                .head(headList)
                .sheet(sheetName)
                .table().head(clazz).needHead(Boolean.FALSE)
                .doWrite(list);
    }


    /**
     * 导出时生成OutputStream
     */
    private static OutputStream getOutputStream(HttpServletResponse response,String fileName) {
        //创建本地文件
        String filePath = fileName + ".xlsx";
        File file = new File(filePath);
        try {
            if (!file.exists() || file.isDirectory()) {
                file.createNewFile();
            }
            fileName = new String(filePath.getBytes(), "ISO-8859-1");
            response.addHeader("Content-Disposition", "filename=" + fileName);
            return response.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 导出时生成OutputStream 不要临时文件
     */
    private static OutputStream handleRequestResponse(HttpServletResponse response, HttpServletRequest request, String fileName){
        String userAgent = request.getHeader("User-Agent");
        try {
            if (userAgent.contains("MSIE") || userAgent.contains("Trident")||userAgent.contains("Edge")) {
                fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
            } else {
                // 非IE浏览器的处理：
                fileName = new String(fileName.getBytes("UTF-8"), "ISO_8859-1");
            }
        } catch (UnsupportedEncodingException e) {
            log.error("导出出错：", e);
        }
        response.setHeader("Content-Disposition", String.format(
                "attachment; filename=\"%s\"", fileName));
        response.setCharacterEncoding("utf8");
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Cache-Control", "no-store");
        response.addHeader("Cache-Control", "max-age=0");
        try {
            return response.getOutputStream();
        } catch (IOException e) {
            log.error("导出出错：", e);
        }
        return null;
    }
}
